Add functionality to set overall opacity of a top-level window. (#405316)
authorTor Lillqvist <tml@novell.com>
Mon, 30 Apr 2007 07:37:24 +0000 (07:37 +0000)
committerTor Lillqvist <tml@src.gnome.org>
Mon, 30 Apr 2007 07:37:24 +0000 (07:37 +0000)
2007-04-30  Tor Lillqvist  <tml@novell.com>

Add functionality to set overall opacity of a top-level
window. (#405316)

* gtk/gtk.symbols: Add gtk_window_set_opacity and
gtk_window_get_opacity.

* gtk/gtkwindow.c (struct _GtkWindowPrivate,
(gtk_window_class_init): Add opacity property, a double in the
range [0, 1].
(gtk_window_set_opacity, gtk_window_get_opacity): Implement.
(gtk_window_realize): If opacity is set, call
gdk_window_set_opacity().

* gtk/gtkwindow.h: Declare gtk_window_set_opacity() and
gtk_window_get_opacity().

svn path=/trunk/; revision=17731

ChangeLog
gtk/gtk.symbols
gtk/gtkwindow.c
gtk/gtkwindow.h

index 3557d84ac18db31ba35adb401c10003673393487..f116491623f0308b30c7793a281f4d9179237e48 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
        that this is not implemented in the Windows backend. Add reference
        to gdk_window_set_opacity().
 
+       * gtk/gtk.symbols: Add gtk_window_set_opacity and
+       gtk_window_get_opacity.
+
+       * gtk/gtkwindow.c (struct _GtkWindowPrivate,
+       (gtk_window_class_init): Add opacity property, a double in the
+       range [0, 1].
+       (gtk_window_set_opacity, gtk_window_get_opacity): Implement.
+       (gtk_window_realize): If opacity is set, call
+       gdk_window_set_opacity().
+
+       * gtk/gtkwindow.h: Declare gtk_window_set_opacity() and
+       gtk_window_get_opacity().
+
 2007-04-30  Matthias Clasen <mclasen@redhat.com>
 
        * gtk/gtk.symbols:
index 6100d68a34036de50b135e3c98cfb0f5b48c4d9b..43b74b5b0f122b4892b7745a53355253d88abad8 100644 (file)
@@ -4730,6 +4730,8 @@ gtk_window_set_keep_above
 gtk_window_set_keep_below
 gtk_window_set_mnemonic_modifier
 gtk_window_set_modal
+gtk_window_set_opacity
+gtk_window_get_opacity
 #ifndef GTK_DISABLE_DEPRECATED
 gtk_window_set_policy
 #endif
index 0b47429f1bd6b5aa481902ad3ac68ff8b56d92ab..a7140aafbbce21cb74fab5e0cfa284cc17a765a6 100644 (file)
@@ -92,6 +92,7 @@ enum {
   PROP_DELETABLE,
   PROP_GRAVITY,
   PROP_TRANSIENT_FOR,
+  PROP_OPACITY,
   
   /* Readonly properties */
   PROP_IS_ACTIVE,
@@ -181,8 +182,12 @@ struct _GtkWindowPrivate
   guint transient_parent_group : 1;
 
   guint reset_type_hint : 1;
+  guint opacity_set : 1;
+
   GdkWindowTypeHint type_hint;
 
+  gdouble opacity;
+
   gchar *startup_id;
 };
 
@@ -726,6 +731,23 @@ gtk_window_class_init (GtkWindowClass *klass)
                                                        P_("The transient parent of the dialog"),
                                                        GTK_TYPE_WINDOW,
                                                        GTK_PARAM_READWRITE| G_PARAM_CONSTRUCT));
+  /**
+   * GtkWindow:opacity:
+   *
+   * The requested opacity of the window. See gtk_window_set_opacity() for
+   * more details about window opacity.
+   *
+   * Since: 2.12
+   */
+  g_object_class_install_property (gobject_class,
+                                  PROP_OPACITY,
+                                  g_param_spec_double ("opacity",
+                                                       P_("Opacity for Window"),
+                                                       P_("The opacity of the window, from 0 to 1"),
+                                                       0.0,
+                                                       1.0,
+                                                       1.0,
+                                                       GTK_PARAM_READWRITE));
 
   window_signals[SET_FOCUS] =
     g_signal_new (I_("set_focus"),
@@ -861,6 +883,7 @@ gtk_window_init (GtkWindow *window)
   priv->focus_on_map = TRUE;
   priv->deletable = TRUE;
   priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
+  priv->opacity = 1.0;
   priv->startup_id = NULL;
 
   colormap = _gtk_widget_peek_colormap ();
@@ -980,6 +1003,9 @@ gtk_window_set_property (GObject      *object,
     case PROP_TRANSIENT_FOR:
       gtk_window_set_transient_for (window, g_value_get_object (value));
       break;
+    case PROP_OPACITY:
+      gtk_window_set_opacity (window, g_value_get_double (value));
+      break;
     default:
       break;
     }
@@ -1091,6 +1117,9 @@ gtk_window_get_property (GObject      *object,
     case PROP_TRANSIENT_FOR:
       g_value_set_object (value, gtk_window_get_transient_for (window));
       break;
+    case PROP_OPACITY:
+      g_value_set_double (value, gtk_window_get_opacity (window));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2079,6 +2108,68 @@ gtk_window_get_transient_for (GtkWindow *window)
   return window->transient_parent;
 }
 
+/**
+ * gtk_window_set_opacity:
+ * @window: a #GtkWindow
+ * @opacity: desired opacity, between 0 and 1
+ *
+ * Request the windowing system to make @window partially transparent,
+ * with opacity 0 being fully transparent and 1 fully opaque. (Values
+ * of the opacity parameter are clamped to the [0,1] range.) On X11
+ * this has any effect only on X screens with a compositing manager
+ * running. See gtk_widget_is_composited(). On Windows it should work
+ * always.
+ * 
+ * Note that setting a window's opacity after the window has been
+ * shown causes it to flicker once on Windows.
+ *
+ * Since: 2.12
+ **/
+void       
+gtk_window_set_opacity  (GtkWindow *window, 
+                        gdouble    opacity)
+{
+  GtkWindowPrivate *priv;
+  
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  priv = GTK_WINDOW_GET_PRIVATE (window); 
+
+  if (opacity < 0.0)
+    opacity = 0.0;
+  else if (opacity > 1.0)
+    opacity = 1.0;
+
+  priv->opacity_set = TRUE;
+  priv->opacity = opacity;
+
+  if (GTK_WIDGET_REALIZED (window))
+    gdk_window_set_opacity (GTK_WIDGET (window)->window, priv->opacity);
+}
+
+/**
+ * gtk_window_get_opacity:
+ * @window: a #GtkWindow
+ *
+ * Fetches the requested opacity for this window. See
+ * gtk_window_set_opacity().
+ *
+ * Return value: the requested opacity for this window.
+ *
+ * Since: 2.12
+ **/
+gdouble
+gtk_window_get_opacity (GtkWindow *window)
+{
+  GtkWindowPrivate *priv;
+  
+  g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
+
+  priv = GTK_WINDOW_GET_PRIVATE (window); 
+
+  return priv->opacity;
+}
+
 /**
  * gtk_window_set_type_hint:
  * @window: a #GtkWindow
@@ -4410,6 +4501,9 @@ gtk_window_realize (GtkWidget *widget)
       window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
                                      &attributes, attributes_mask);
                                                 
+      if (priv->opacity_set)
+       gdk_window_set_opacity (window->frame, priv->opacity);
+
       gdk_window_set_user_data (window->frame, widget);
       
       attributes.window_type = GDK_WINDOW_CHILD;
@@ -4449,6 +4543,9 @@ gtk_window_realize (GtkWidget *widget)
   
   widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
 
+  if (!window->has_frame && priv->opacity_set)
+    gdk_window_set_opacity (widget->window, priv->opacity);
+
   gdk_window_enable_synchronized_configure (widget->window);
     
   gdk_window_set_user_data (widget->window, window);
index c1ff6892d3bb8ef8cd76cff683433e428713bbee..c32dc5946ed22ea6af6874c0204038331013c698 100644 (file)
@@ -198,6 +198,9 @@ gboolean   gtk_window_activate_default             (GtkWindow           *window);
 void       gtk_window_set_transient_for        (GtkWindow           *window, 
                                                GtkWindow           *parent);
 GtkWindow *gtk_window_get_transient_for        (GtkWindow           *window);
+void       gtk_window_set_opacity              (GtkWindow           *window, 
+                                               gdouble              opacity);
+gdouble    gtk_window_get_opacity              (GtkWindow           *window);
 void       gtk_window_set_type_hint            (GtkWindow           *window, 
                                                GdkWindowTypeHint    hint);
 GdkWindowTypeHint gtk_window_get_type_hint     (GtkWindow           *window);